Packer + Ansible + ECRを使ったDcokerコンテナイメージ作成の自動化
コンニチハ、千葉です。
Dockerコンテナを運用する際、自動化することで沢山のメリットがあります。今回はAWSとも親和性の高い、Packerを利用してコンテナイメージを作成して、ECRへpushしてみました。プロビジョニングツールとしては、弊社で利用頻度の高いAnsibleを使います。
環境
今回は、試しに以下で実施しました。roleはlangesを変更するだけです。
├── ansible │ ├── group_vars │ │ └── dev-nginx.yml │ ├── playbooks │ │ └── nginx.yml │ └── roles │ ├── stage │ │ └── tasks │ │ └── main.yml │ └── system │ ├── lang │ │ ├── defaults │ │ │ └── main.yml │ │ └── tasks │ │ ├── main.yml └── packer-nginx.json
ansibleディレクトリにplaybookを格納します。packer-nbinx.jsonにコンテナイメージの定義や、pushするECRのパラメータを記載します。
Packer用のファイル
packer-nginx.json
ハイライトされているパラメータを適宜変更します。
{ "variables": { "ecr_login_pass": "{{env `ecr_cred`}}", "ecr_repo": "XXXXXXXXXXX.dkr.ecr.us-east-1.amazonaws.com/nginx", "ecr_url": "https://XXXXXXXXXXX.dkr.ecr.us-east-1.amazonaws.com", "docker_image": "centos:6", "ansible_playbook": "ansible/playbooks/nginx.yml", "ansible_extra_vars": "--extra-vars env=dev-nginx" }, "builders":[{ "type": "docker", "image": "{{user `docker_image`}}", "commit": "true" }], "provisioners":[ { "type": "shell", "inline": [ "yum -y update", "yum -y install epel-release", "yum -y install ansible" ] }, { "type": "ansible-local", "playbook_file": "{{user `ansible_playbook`}}", "extra_arguments": "{{user `ansible_extra_vars`}}", "role_paths": ["ansible/roles/stage","ansible/roles/system"], "group_vars": "ansible/group_vars" } ], "post-processors": [ [ { "type": "docker-tag", "repository": "{{user `ecr_repo`}}", "tag": "0.7" }, { "type": "docker-push", "login": true, "login_email": "none", "login_username": "AWS", "login_password": "{{user `ecr_login_pass`}}", "login_server": "{{user `ecr_url`}}" } ] ] }
ECRログイン時のパスワードは、aws ecr get-login --region us-east-1
で取得する必要があります。このパスワードは定期的に変わるので変数で読み込みするように対応しています。"ecr_login_pass": "{{env `ecr_cred`}}"
の部分がそれになります。
また"ansible_extra_vars": "--extra-vars env=dev-nginx"
を変更することで、環境毎に変数を利用するようにしています。くわしくはこちら
Ansible用のファイル
今回はOSのlangを変更するplaybookで試しました。
ansible/playbooks/nginx.yml
# # remote-log.yml # # ansible-playbook --extra-vars "env=dev-log" remote-log.yml - hosts: all become: yes roles: - { role: stage } - { role: system/lang, tags: ['system'] }
ansible/group_vars/dev-nginx.yml
--- lang: C
ansible/roles/system/lang/defaults/main.yml
--- lang: ja_JP.UTF-8
ansible/roles/system/lang/defaults/main.yml
このroleはAmazon Linuxを想定しています。
--- - name: set LANG={{ lang }} in /etc/sysconfig/i18n lineinfile: dest=/etc/sysconfig/i18n regexp=^LANG= line='LANG={{ lang }}' state=present - name: set locale in /etc/cloud/cloud.cfg (AmazonLinux) lineinfile: "dest=/etc/cloud/cloud.cfg regexp='^locale' line='locale: {{ lang }}' state=present" when: ansible_distribution == 'Amazon'
ansible/roles/stage/tasks/main.yml
- group_by: key={{ env }}
実行方法
ECRのログインパスワードを変数に格納してから、Packerのコマンドを実行します。
export ecr_cred=$(aws ecr get-login --region us-east-1 | cut -d ' ' -f6) packer build ./packer-nginx.json
まとめ
PakcerがECRに対応しているので、マネージドでプライベートなコンテナリポジトリを簡単に利用でき運用の手間が減ります。また、Dockerコンテナイメージ作成もコード化で管理できてこれまた、便利です。 AWSでDocker運用するにはかなり強力なツールだと思います。
参考
https://www.packer.io/docs/builders/docker.html